import json

from celery import shared_task
from apps.HttpTestcase.models import Testsuite
from apps.HttpTestcase.core.utils import get_version
import threading
from apps.HttpTestcase.core.http_dlient import HttpSession
from apps.HttpTestcase.core.http_testsuite_run import HttpTestsuiteRun
from apps.HttpTestcase.models.testcase_reports import TestcaseReports
from apps.HttpTestcase.models.testcases import Testcases
from apps.HttpTestcase.models.testcase_testsuite_reports import TestsuiteTestcaseReports
from apps.HttpTestcase.core.http_global_variable_pool import Variable_Pool
from utils.send_report import DingDingWebHook
from decimal import Decimal


def run_testsuite(testsuite=None, version=None, http_session_params=None, is_testsuite_set=False):
    # 组织统计场景下用例信息返回，用于发送报告
    testsuite_statistics = {
        'testcase_num': 0,
        'pass_num': 0,
        'fail_num': 0,
        'elapsed_ms': 0,
        'version': ''
    }

    for testsuite in testsuite:
        project = testsuite.project
        # 获取场景集所属项目环境
        envs = project.default_envs
        env_param = envs.param
        project_param = project.param

        if is_testsuite_set:
            http_session_params.update_output_variable(env_param)
            http_session_params.update_output_variable(project_param)
        else:
            if isinstance(project_param, str):
                project_param = json.loads(project_param)
            http_session_params = Variable_Pool(env_param=env_param, project_param=project_param)

            # if str(project_param) == '{}':
            #     http_session_params = Variable_Pool(env_param=env_param)
            # else:
            #     http_session_params = Variable_Pool(project_param=project_param)

        # 创建全局变量池实例
        # http_global_variable = Variable_Pool()
        # 4创建HttpSession实例
        http_session = HttpSession()
        # 5创建HttpTestcaseRunner实例
        http_testsuite_run = HttpTestsuiteRun(project=project, envs=envs, testsuite=testsuite,
                                              http_session=http_session, http_session_params=http_session_params)

        # 运行后拿到testsuite报告、testcase报告列表
        testsuite_reports, testcase_reports_list = http_testsuite_run.run()
        testsuite_statistics['testcase_num'] = testsuite_reports.total_num
        testsuite_statistics['pass_num'] = testsuite_reports.passed_num
        testsuite_statistics['fail_num'] = testsuite_reports.failed_num
        testsuite_statistics['elapsed_ms'] = testsuite_reports.elapsed_ms
        testsuite_statistics['version'] = version

        testsuite_reports.version = version

        # 拿到用例列表，更新测试用例报告及用例状态
        testcase_list = []
        pass_num = 0
        fail_num = 0

        # 循环报告列表组织数据
        for testcase_report in testcase_reports_list:
            testcase_report.is_testsuite = True
            testcase_report.testsuite_reports = testsuite_reports
            testcase_report.version = version
            testcase = testcase_report.testcase
            if testcase_report.testcase == 'PASS':
                pass_num += 1
            else:
                fail_num += 1
            testcase.status = testcase_report.status
            testcase_list.append(testcase)

        testsuite_reports.save()
        # 2、更新场景状态
        testsuite.status = testsuite_reports.status
        testsuite.save()

        TestcaseReports.objects.bulk_create(testcase_reports_list)
        Testcases.objects.bulk_update(testcase_list, fields=['status'])
    return testsuite_statistics


@shared_task(name="批量执行测试场景:apps.CeleryTimedTask.HttpTestcase.testsuite_task.batch_exec_testsuite")
def batch_exec_testsuite(testsuites=None, version=None):
    """
    为场景分配线程
    """
    pass
    if not version:
        version = get_version()

    if isinstance(testsuites, str):
        testsuites = eval(testsuites) if isinstance(eval(testsuites), list) else []
    testsuite_list = Testsuite.objects.filter(id__in=testsuites, is_delete=False)

    # 线程数量
    thread_num = 5
    # Q每个线程多少任务   R剩余
    Q, R = divmod(len(testsuite_list), thread_num)

    # 生成线程对应数量的列表
    testcases_temp = [[] for i in range(thread_num)]

    # 每次取出Q个用例放入testcases_temp里的list中
    for i in range(thread_num):
        testcases_temp[i] = testsuite_list[i * Q:(i + 1) * Q]

    for i in range(R):
        testcases_temp[i].append(testsuite_list[Q * R + i])

    # 给线程分配任务并启动
    threads = []
    for y in range(thread_num):
        t = threading.Thread(target=run_testsuite, args=(testcases_temp[y], version))
        threads.append(t)

    for t in threads:
        t.start()
